﻿// Fill out your copyright notice in the Description page of Project Settings.


#include "Player/OtherWorldPlayerController.h"

#include "EnhancedInputComponent.h"
#include "EnhancedInputSubsystems.h"
#include "Input/OtherWorldInputComponent.h"

AOtherWorldPlayerController::AOtherWorldPlayerController()
{
	//可以进行复制
	bReplicates = true;
}

void AOtherWorldPlayerController::PlayerTick(float DeltaTime)
{
	Super::PlayerTick(DeltaTime);
	//每帧的光标检查
	CursorTrace();
}

void AOtherWorldPlayerController::BeginPlay()
{
	Super::BeginPlay();
	check(OtherWorldContext);
	//多人游戏中，不是本地玩家无法通过GetLocalPlayer获取到对应自己的输入组件所以需要做空指针判断
	UEnhancedInputLocalPlayerSubsystem* Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(GetLocalPlayer());
	if (Subsystem)
	{
		Subsystem->AddMappingContext(OtherWorldContext, 0);
	}
	
	//设置鼠标光标
	bShowMouseCursor = true;
	DefaultMouseCursor = EMouseCursor::Default;
	//设置鼠标是否隐藏，是否锁定再屏幕中，设置后游戏运行时也会有鼠标光标
	FInputModeGameAndUI InputModeData;
	InputModeData.SetLockMouseToViewportBehavior(EMouseLockMode::DoNotLock);
	InputModeData.SetHideCursorDuringCapture(false);
	SetInputMode(InputModeData);
}

void AOtherWorldPlayerController::SetupInputComponent()
{
	Super::SetupInputComponent();
	UOtherWorldInputComponent* AuraInputComponent = CastChecked<UOtherWorldInputComponent>(InputComponent);
	AuraInputComponent->BindAction(MoveAction, ETriggerEvent::Triggered, this, &AOtherWorldPlayerController::Move);
}

void AOtherWorldPlayerController::Move(const FInputActionValue& InputActionValue)
{
	//获取输入向量
	const FVector2D InputAxisVector = InputActionValue.Get<FVector2D>();
	//获取控制器的旋转
	const FRotator Rotation = GetControlRotation();
	//创建一个新的选择器，只保留控制器的(Y轴旋转)
	const FRotator YawRotation(0.f, Rotation.Yaw, 0.f);

	//通过 GetUnitAxis() 获取指定轴向的单位向量：
	//因为角色没有旋转90度，和胶囊体的箭头方向一直
	//EAxis::Y: 获取Y轴方向（前方）
	//EAxis::X: 获取X轴方向（右方）
	//根据X轴选择计算出向前的向量
	const FVector ForwardDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::Y);
	//根据y轴选择计算出向右的向量
	const FVector RightDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X);
	//通过运动组件在向前的向量上加上鼠标获取的y轴坐标,向右的向量上加上鼠标获取的x轴坐标
	if (APawn* ControlledPawn = GetPawn<APawn>())
	{
		ControlledPawn->AddMovementInput(ForwardDirection, InputAxisVector.Y);
		ControlledPawn->AddMovementInput(RightDirection, InputAxisVector.X);
	}
}

void AOtherWorldPlayerController::CursorTrace()
{
	/**
	 *GetHitResultUnderCursor 是Unreal Engine中用于执行点击测试（Hit Test）的函数，通常在游戏或应用中用于检测鼠标光标下方的对象。
	 *ECC_Visibility - 这是一个碰撞通道（Collision Channel），指定要检测的物体类型。ECC_Visibility 通常用于检测可见物体
	 **/
	//这里需要根据魔法圈是否激活来判断使用的检测通道
	GetHitResultUnderCursor(ECC_Visibility, false, CursorHit);
	if (!CursorHit.bBlockingHit) return;
}
